from numpy import *
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider


class VectorTransform3d:
    Xangslider = yangslider = zangslider = 0
    MyAngX = MyAngY = MyAngZ = 0.0

    def __init__(self, Vector: matrix):
        self.fig = plt.gcf()
        self.ax = plt.axes(projection="3d")
        left, bottom, width, height = 0.15, 0.02, 0.7, 0.05
        slider_ax = plt.axes([left, bottom + 0.1, width, height])
        slider_ay = plt.axes([left, bottom + 0.05, width, height])
        slider_az = plt.axes([left, bottom, width, height])
        self.Xangslider = Slider(slider_ax, 'x-ang', valmin=0.0, valmax=360.0, valinit=0)
        self.yangslider = Slider(slider_ay, 'y-ang', valmin=0.0, valmax=360.0, valinit=0)
        self.zangslider = Slider(slider_az, 'z-ang', valmin=0.0, valmax=360.0, valinit=0)
        self.Xangslider.on_changed(self.XangUpdate)
        self.yangslider.on_changed(self.YangUpdate)
        self.zangslider.on_changed(self.ZangUpdate)

        plt.subplots_adjust(left=left, bottom=0.35)  # Make space for the slider
        self.My_V = Vector

    def XangUpdate(self, vel):
        self.MyAngX = vel
        self.displayUpdate()

    def YangUpdate(self, vel):
        self.MyAngY = vel
        self.displayUpdate()

    def ZangUpdate(self, vel):
        self.MyAngZ = vel
        self.displayUpdate()

    def displayUpdate(self):
        oldelev = self.ax.elev
        oldazim = self.ax.azim
        plt.delaxes(self.ax)
        NewV = self.TransformVector3d()
        self.ax = plt.axes(projection="3d")
        self.ax.elev = oldelev
        self.ax.azim = oldazim
        self.ax.quiver(0, 0, 0, self.My_V[0, 0], self.My_V[1, 0], self.My_V[2, 0], length=1.0, color="k")
        self.ax.quiver(0, 0, 0, NewV[0, 0], NewV[1, 0], NewV[2, 0], length=1.0, color="k")
        self.ax.quiver(0, 0, 0, 1, 0, 0, length=1.0, color="r")
        self.ax.quiver(0, 0, 0, 0, 1, 0, length=1.0, color="g")
        self.ax.quiver(0, 0, 0, 0, 0, 1, length=1.0, color="b")
        self.ax.set_xlim(-2, 2)
        self.ax.set_ylim(-2, 2)
        self.ax.set_zlim(-2, 2)
        self.fig.canvas.draw()

    def display(self):
        self.displayUpdate()

        plt.show()

    def TransformVector3d(self):
        radx = deg2rad(self.MyAngX)
        rady = deg2rad(self.MyAngY)
        radz = deg2rad(self.MyAngZ)
        XtransformM = mat([
            [1, 0, 0],
            [0, cos(radx), -sin(radx)],
            [0, sin(radx), cos(radx)]
        ])
        YtransformM = mat([
            [cos(rady), 0, sin(rady)],
            [0, 1, 0],
            [-sin(rady), 0, cos(rady)]
        ])
        ZtransformM = mat([
            [cos(radz), -sin(radz), 0],
            [sin(radz), cos(radz), 0],
            [0, 0, 1]
        ])
        tmp = XtransformM * YtransformM * ZtransformM * self.My_V
        return tmp


V = mat([
    [0],
    [1],
    [0]
])

tmp = VectorTransform3d(V)
tmp.display()
